package com.oyb.util;

import com.alibaba.druid.pool.DruidDataSource;
import com.alibaba.druid.pool.DruidDataSourceFactory;

import javax.sql.DataSource;
import java.sql.*;

public class ConnectionUtils {
    //声明连接池对象
    private static DruidDataSource druidDataSource;

    //静态代码块全局加载 数据库驱动 1次——交给连接池来做
    static {
            try {
                //初始化Druid连接池
                druidDataSource = (DruidDataSource) DruidDataSourceFactory.createDataSource(PropertiesUtils.getPropertiesObj());
            } catch (Exception e) {
                e.printStackTrace();
            }
    }
    //1.开启事务，并存放到ThreadLocal中
    private static ThreadLocal<Connection> threadLocal = new ThreadLocal<>();
    private static ThreadLocal<Integer> threadLocal2 = new ThreadLocal<>();//访问begin次数的累加器
    public static void begin(){
        Connection connection = threadLocal.get();
        //说明没有人把连接存到threadlocal中，换句话讲就是没人开启事务，
        if(connection == null){
            // 则我们需要1.调用方法开启新的连接,2.开启事务，3.并把连接存放到threadlocal中。
            connection = getconnection();
            try {
                connection.setAutoCommit(false);//关闭默认的自动提交，就变成了手动提交，就是开启事务
                threadLocal2.set(1);
            } catch (SQLException throwables) {
                throwables.printStackTrace();
            }
            threadLocal.set(connection);//把连接存放到threadlocal中
        }else{
            Integer count = threadLocal2.get();
            threadLocal2.set(++count);
        }
    }
//1.1创建连接
    public static Connection getconnection(){
        //后面的dao层每次获取连接都要进行判断threadLocal中有没有连接，如果有，说明开启了事务，那么只需要拿事务中的连接就行，这样就可以保证同一个连接
        //如果是空的，说明没有开启事务，也就是这个业务只需要单次操作数据库不需要事务，只需要正常获得一个新的连接就行
        Connection connection = threadLocal.get();
        if(connection != null){
            return connection;
        }
        try {
            //获取连接需要从Druid连接池中获取
            return druidDataSource.getConnection();
        } catch (SQLException throwables) {
            throwables.printStackTrace();
        }
        return null;
    }

    //2.提交事务
    public static void commit(){
        Connection connection = threadLocal.get();
        if(connection != null){
            Integer count = threadLocal2.get();
            if (count == 1){
                try {
                    connection.commit();
                    connection.close();//提交代表事务正常结束了，数据库有数据了，可以关闭连接
                    //清空ThreadLocal
                    threadLocal.remove();
                    threadLocal2.remove();
                } catch (SQLException throwables) {
                    throwables.printStackTrace();
                }
            }else{
                threadLocal2.set(--count);
            }

        }
    }
    //3.回滚事务
    public static void roolback(){
        Connection connection = threadLocal.get();
        if(connection != null){
            Integer count = threadLocal2.get();
            if (count == 1) {
                try {
                    connection.rollback();
                    connection.close();//回滚代表事务异常结束了，数据库有数据了，可以关闭连接
                    //清空ThreadLocal
                    threadLocal.remove();
                    threadLocal2.remove();
                } catch (SQLException throwables) {
                    throwables.printStackTrace();
                }
            }
            else{
                threadLocal2.set(--count);
            }
        }
    }
    //无事务的关闭连接
//    public static void close(AutoCloseable... p){
//        if(p.length!=0)
//            for (int i = 0; i < p.length; i++) {
//                try {
//                    p[i].close();
//                } catch (Exception e) {
//                    e.printStackTrace();
//                }
//            }
//    }

    //无事务的关闭连接
    public static void close( Statement statement, Connection connection,ResultSet resultSet){
        if (resultSet != null) {
            try {
                resultSet.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }

        if (statement != null) {
            try {
                statement.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }

        if (connection != null) {
            try {
                //如果当前无事务，才关闭连接；有事务的则在事务的方法的提交或者回滚后关闭
                if (connection.getAutoCommit()) {
                    connection.close();
                }
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
    }
}
